#include "aerial\Game\GameObject\GameObject.h"

#include <iostream>

using namespace air;
using namespace std;

b2World* GameObject::world = 0;
const int GameObject::MaxRegulationCount = 10;

void GameObject::SetWorld(b2World* _world) { world = _world;}

void GameObject::initialize()
{
	float bx, by;
	//adjusted = false;
	toDestroy = false;
	remoteDevA = 0.f; 
	remoteDevT.Set(0.f, 0.f);
	//VScale = 0.f;
	BattleHelper::getBox2dCoordinateFromHge(bx, by, T.x, T.y);

	// create body
	b2BodyDef bodyDef;
	bodyDef.type = b2_dynamicBody;
	bodyDef.fixedRotation = true;
	bodyDef.position.Set(bx, by);
	body = world->CreateBody(&bodyDef);
	body->SetUserData((void*)this);
	// other features(fixture shape) are decided by son class
}

GameObject::GameObject(float x, float y, int _id, float _rot)
	: IObject(), body(0), T(x, y), V(0.f, 0.f), A(_rot), id(_id) 
{
	b2Rot a(_rot);
	A = a.GetAngle();
	D = -a.GetYAxis();
	initialize();
}

/// @biref construct using position and direction vector
GameObject::GameObject(float x, float y, float vx, float vy, int _id)
	: IObject(), body(0), T(x, y), V(0.f, 0.f), D(vx, vy), id(_id) 
{
	D.Normalize();
	//might not work;
	A = atan2(D.x, -D.y);
	if (A < 0) A += b2_pi * 2;
	initialize();
}

bool GameObject::update(float dt)
{
	adjusted = false;
	if (regulationTime > 0) {
		regulationTime -= dt;
		adjusted = true;
		V += remoteDevT;
		body->SetLinearVelocity(V);
	}
	return false;
}

/// @brief position transform try to avoid for performance
void GameObject::SetTransform(float _x, float _y)
{
	T.x = _x;
	T.y = _y;
	b2Vec2 a = BattleHelper::getBox2dCoordinateFromHge(T);
	body->SetTransform(a, 0.f);
}

void GameObject::RegulateDeviation()
{
	regulationTime = 0.1f;
	SetRotate(remoteDevA);
	SetSpeed(remoteDevV);
	remoteDevV.SetZero();
	remoteDevT.Set(
		(remoteDevT.x - T.x) / 300,
		(remoteDevT.y - T.y) / 300
	);
}
